﻿using System;
using System.Collections.Generic;
using GeoAPI.Geometries;
using NetTopologySuite.GeometriesGraph;

namespace NetTopologySuite.Operation.Relate
{
	public class RelateNodeGraph
	{
		public IEnumerator<Node> GetNodeEnumerator()
		{
			return this._nodes.GetEnumerator();
		}

		public void Build(GeometryGraph geomGraph)
		{
			this.ComputeIntersectionNodes(geomGraph, 0);
			this.CopyNodesAndLabels(geomGraph, 0);
			IList<EdgeEnd> ee = new EdgeEndBuilder().ComputeEdgeEnds(geomGraph.Edges);
			this.InsertEdgeEnds(ee);
		}

		public void ComputeIntersectionNodes(GeometryGraph geomGraph, int argIndex)
		{
			foreach (Edge edge in geomGraph.Edges)
			{
				Location location = edge.Label.GetLocation(argIndex);
				foreach (EdgeIntersection edgeIntersection in edge.EdgeIntersectionList)
				{
					RelateNode relateNode = (RelateNode)this._nodes.AddNode(edgeIntersection.Coordinate);
					if (location == Location.Boundary)
					{
						relateNode.SetLabelBoundary(argIndex);
					}
					else if (relateNode.Label.IsNull(argIndex))
					{
						relateNode.SetLabel(argIndex, Location.Interior);
					}
				}
			}
		}

		public void CopyNodesAndLabels(GeometryGraph geomGraph, int argIndex)
		{
			foreach (Node node in geomGraph.Nodes)
			{
				this._nodes.AddNode(node.Coordinate).SetLabel(argIndex, node.Label.GetLocation(argIndex));
			}
		}

		public void InsertEdgeEnds(IList<EdgeEnd> ee)
		{
			foreach (EdgeEnd e in ee)
			{
				this._nodes.Add(e);
			}
		}

		private readonly NodeMap _nodes = new NodeMap(new RelateNodeFactory());
	}
}
